#pragma once
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include<unistd.h>
#include"inet_addr.hpp"
#include"log.hpp"

class UdpServer{
    public:
        UdpServer(uint16_t port):_port(port),_socketfd(-1){
            _socketfd=socket(AF_INET,SOCK_DGRAM,0);
            if(_socketfd==-1){
                std::cout<<"Error in creating socket"<<std::endl;
                return;
            }
            struct sockaddr_in socket_addr;
            memset(&socket_addr,0,sizeof(socket_addr));
            socket_addr.sin_family=AF_INET;
            socket_addr.sin_addr.s_addr=INADDR_ANY;
            socket_addr.sin_port=htons(port);
            //绑定端口
            if(bind(_socketfd,(struct sockaddr*)&socket_addr,sizeof(socket_addr))==-1){
                LOG(ly::LogLevel::ERROR)<<"绑定失败"<<'\n';
                perror("bind failed");
                close(_socketfd);
                return;
            }
        }
        void Send(const std::string& message){
            if(_socketfd==-1){
                LOG(ly::LogLevel::ERROR)<<"套接字未创建"<<'\n';
                return;
            }

        }
        void Start(){
            char buffer[1024];
            while(true){
                memset(buffer,0,sizeof(buffer));
                struct sockaddr_in clientaddr;
                socklen_t addrlen=sizeof(clientaddr);
                memset(&clientaddr,0,addrlen);
                ssize_t n=recvfrom(_socketfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&clientaddr,&addrlen);
                if(n==-1){
                    LOG(ly::LogLevel::ERROR)<<"读取错误";
                    perror("recvfrom failed");
                    close(_socketfd);
                    return;
                }
                else{
                    InetAddr client_addr(clientaddr);
                    LOG(ly::LogLevel::ERROR)<<"接收到消息: "<<buffer<<" 来自 "<<client_addr.PrintDebug()<<'\n';
                    std::cin>>buffer;
                    sendto(_socketfd,buffer,n,0,(struct sockaddr*)&clientaddr,addrlen);
                }
            }
        }
        void getLocalAddr() {
            struct sockaddr_in addr;
            socklen_t len = sizeof(addr);
            // 获取套接字绑定的本地地址
            if (getsockname(_socketfd, (struct sockaddr*)&addr, &len) == -1) {
                perror("getsockname failed");
                return;
            }
            // 转换IP为字符串
            char ip[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
            // 转换端口为本地字节序
            uint16_t port = ntohs(addr.sin_port);
            std::cout << "本地绑定的IP: " << ip << ", 端口: " << port << std::endl;
        }
        ~UdpServer(){
            close(_socketfd);
        }
    private:
        int _socketfd;
        uint16_t _port;
        
};